/*

  xmunipack - config

  Copyright © 2009-2011 F.Hroch (hroch@physics.muni.cz)

  This file is part of Munipack.

  Munipack is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.
  
  Munipack is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
  
  You should have received a copy of the GNU General Public License
  along with Munipack.  If not, see <http://www.gnu.org/licenses/>.

*/

#include "xmunipack.h"
#include <wx/wx.h>
#include <wx/config.h>
#include <wx/stdpaths.h>
#include <wx/artprov.h>
#include <wx/filename.h>

// config
#define MUNIBROWSE_WIDTH     "MuniBrowse_width"
#define MUNIBROWSE_HEIGHT    "MuniBrowse_height"
#define MUNIBROWSE_ICONLIST  "MuniBrowse_iconlist"
#define MUNIBROWSE_LABELTYPE "MuniBrowse_labeltype"
#define MUNIBROWSE_LABELKEY  "MuniBrowse_labelkey"
#define MUNIBROWSE_SORTTYPE  "MuniBrowse_sorttype"
#define MUNIBROWSE_SORTKEY   "MuniBrowse_sortkey"
#define MUNIBROWSE_REVERSE   "MuniBrowse_reverse"
#define MUNIBROWSE_SASH      "MuniBrowse_sash"
#define MUNIBROWSE_COLLECTOR "MuniBrowse_collector"
#define MUNIBROWSE_TBAR      "MuniBrowse_tbar"
#define MUNIVIEW_WIDTH       "MuniView_width"
#define MUNIVIEW_HEIGHT      "MuniView_height"
#define MUNIVIEW_TBAR        "MuniView_tbar"
#define MUNIDETAIL_SCALE     "MuniDetail_scale"
#define MUNIDETAIL_ZOOM      "MuniDetail_zoom"
#define MUNICONSOLE_WIDTH    "MuniConsole_width"
#define MUNICONSOLE_HEIGHT   "MuniConsole_height"
#define MUNICONSOLE_WRAP     "MuniConsole_wrap"
#define MUNIHELP_WIDTH       "MuniHelp_width"
#define MUNIHELP_HEIGHT      "MuniHelp_height"
#define MUNIHEADER_WIDTH     "MuniHeader_width"
#define MUNIHEADER_HEIGHT    "MuniHeader_height"
#define ASTROMETRY_NMATCH    "Astrometry_nmatch"
#define ASTROMETRY_MAXMATCH  "Astrometry_maxmatch"
#define ASTROMETRY_UNITS     "Astrometry_units"
#define ICON_SIZE            "Icon_size"
#define ICON_SMALL           "Icon_small"
#define ICON_ZOOM            "Icon_zoom"
#define SCROLL_RATE          "Scroll_rate"
#define DISPLAY_ITT          "Display_itt" 
#define DISPLAY_PAL          "Display_pal" 
#define DISPLAY_TYPE         "Display_type" 
#define DISPLAY_ZOOM         "Display_zoom" 
#define DISPLAY_NVISION      "Display_nvision"
#define FITS_OBJECT          "Fits_object"
#define FITS_OBSERVER        "Fits_observer"
#define FITS_EXPOSURE        "Fits_exposure"
#define FITS_FILTER          "Fits_filter"
#define FITS_DATEOBS         "Fits_dateobs"
#define COLOR_DISPLAY        "Display_colorspace"
#define COLOR_TEMPERATURE    "Color_temperature"
#define COLOR_WHITEPOINT_U   "Color_whitepoint_u"
#define COLOR_WHITEPOINT_V   "Color_whitepoint_v"
#define CDATAFILE            "Colorspace_data"


MuniConfig::MuniConfig():
  wxConfig(wxEmptyString,wxEmptyString,wxEmptyString,wxEmptyString,
	   wxCONFIG_USE_SUBDIR|wxCONFIG_USE_GLOBAL_FILE|wxCONFIG_USE_LOCAL_FILE),
  dirmask("*.fits*;*.fit*;*.fts*;*.FITS*;*.FTS*;*.FIT*"),
  rawmask("*.cr2;*.crw;*.CR2;*.CRW;*.RAW")
{
  // workaround to create config dir
  // http://article.gmane.org/gmane.comp.lib.wxwindows.general/58942/match=wxCONFIG%5fUSE%5fSUBDIR)
#if !defined(__WXMSW__) || wxUSE_CONFIG_NATIVE

  wxStandardPathsBase &stdpaths = wxStandardPathsBase::Get();
  confdir = stdpaths.GetUserDataDir() + "/";
  //  confdir.Replace("xmunipack","munipack");

  wxFileName dir(confdir);
  if( ! dir.DirExists() ) {
    if( dir.Mkdir() )
      wxLogDebug("Directory "+dir.GetFullPath()+" successfully created.");
    else
      wxLogFatalError("Failed to create of config directory '"+
		      dir.GetFullPath()+"' in your home folder.");
  }
#endif

  // initial browser window size
  int x,y,width,height,w,h,k;
  ::wxClientDisplayRect(&x,&y,&width,&height);


  wxString val;

  Read(MUNIBROWSE_WIDTH,&w,3*width/5);
  Read(MUNIBROWSE_HEIGHT,&h,3*height/5);
  browser_size = wxSize(w,h);
  Read(MUNIBROWSE_SASH,&browser_sash,133);
  Read(MUNIBROWSE_COLLECTOR,&browser_collector,1);
  Read(MUNIBROWSE_TBAR,&browser_tbar,1);

  Read(MUNIVIEW_WIDTH,&w,4*width/5);
  Read(MUNIVIEW_HEIGHT,&h,4*height/5);
  Read(MUNIVIEW_TBAR,&view_tbar,1);
  view_size = wxSize(w,h);

  Read(MUNIDETAIL_SCALE,&detail_scale,4);
  Read(MUNIDETAIL_ZOOM,&detail_zoom,40);

  Read(MUNICONSOLE_WIDTH,&w,width/2);
  Read(MUNICONSOLE_HEIGHT,&h,height/2);
  console_size = wxSize(w,h);

  Read(MUNICONSOLE_WRAP,&console_wrap,0);

  Read(MUNIHELP_WIDTH,&w,3*width/5);
  Read(MUNIHELP_HEIGHT,&h,4*height/5);
  help_size = wxSize(w,h);

  Read(MUNIHEADER_WIDTH,&w,width/2);
  Read(MUNIHEADER_HEIGHT,&h,4*height/5);
  header_size = wxSize(w,h);

  Read(ASTROMETRY_NMATCH,&astrometry_nmatch,7);
  Read(ASTROMETRY_MAXMATCH,&astrometry_maxmatch,30);
  Read(ASTROMETRY_UNITS,&astrometry_units,"arcsec");

  Read(ICON_SIZE,&icon_size,150);
  Read(ICON_SMALL,&icon_small,30);
  Read(ICON_ZOOM,&icon_zoom,0);
  Read(SCROLL_RATE,&scroll_rate,10);

  Read(MUNIBROWSE_ICONLIST,&k,0);
  switch(k){
  case 0:  browser_iconlist = wxLC_ICON; break;
  case 1:  browser_iconlist = wxLC_REPORT; break;
  default: browser_iconlist = wxLC_ICON;
  }

  Read(MUNIBROWSE_LABELTYPE,&k,0);
  switch(k){
  case 0:  browser_labeltype = ID_LABEL_FILENAME; break;
  case 1:  browser_labeltype = ID_LABEL_OBJECT;   break;
  case 2:  browser_labeltype = ID_LABEL_DATEOBS;  break;
  case 3:  browser_labeltype = ID_LABEL_FILTER;   break;
  case 4:  browser_labeltype = ID_LABEL_EXPOSURE; break;
  case 5:  browser_labeltype = ID_LABEL_KEY;      break;
  case 6:  browser_labeltype = ID_LABEL_NO;       break;
  default: browser_labeltype = ID_LABEL_FILENAME;
  }


  Read(MUNIBROWSE_LABELKEY,&browser_labelkey,"");

  Read(MUNIBROWSE_SORTTYPE,&k,0);
  switch(k){
  case 0:  browser_sorttype = ID_SORT_FILENAME; break;
  case 1:  browser_sorttype = ID_SORT_OBJECT;   break;
  case 2:  browser_sorttype = ID_SORT_DATEOBS;  break;
  case 3:  browser_sorttype = ID_SORT_FILTER;   break;
  case 4:  browser_sorttype = ID_SORT_EXPOSURE; break;
  case 5:  browser_sorttype = ID_SORT_SIZE;     break;
  case 6:  browser_sorttype = ID_SORT_KEY;      break;
  default: browser_sorttype = ID_SORT_FILENAME;
  }

  Read(MUNIBROWSE_SORTKEY,&browser_sortkey,"");
  Read(MUNIBROWSE_REVERSE,&browser_reverse,0);

  Read(DISPLAY_ITT,&val,wxEmptyString);
  display_itt = ITT_LINE;
  for(int i = ITT_FIRST+1; i < ITT_LAST; i++) {
    if( val == FitsItt::Type_str(i) )
      display_itt = i;
  }
  // bad horible, solution, needs to be implemented via iterators, strings

  Read(DISPLAY_PAL,&val,wxEmptyString);
  display_pal = PAL_GREY;
  for(int i = PAL_FIRST+1; i < PAL_LAST; i++) {
    if( val == FitsPalette::Type_str(i) )
      display_pal = i;
  }
  // bad horible, solution, needs to be implemented via iterators, strings

  Read(DISPLAY_ZOOM, &display_zoom, -1.0);
  Read(DISPLAY_NVISION, &display_nvision, 0);

  Read(FITS_OBJECT, &fits_object, "OBJECT");
  Read(FITS_OBSERVER, &fits_observer, "OBSERVER");
  Read(FITS_DATEOBS, &fits_dateobs, "DATE-OBS");
  Read(FITS_EXPOSURE, &fits_exposure, "EXPOSURE,EXPTIME");
  Read(FITS_FILTER, &fits_filter, "FILTER");

  Read(COLOR_DISPLAY, &display_colorspace, "sRGB");
  Read(COLOR_TEMPERATURE, &color_temperature, 6504.0);
  Read(COLOR_WHITEPOINT_U, &color_uwhitepoint, 0.19784);
  Read(COLOR_WHITEPOINT_V, &color_vwhitepoint, 0.46831);
#ifdef MUNIPACK_DATA_PATH
  Read(CDATAFILE, &cdatafile, wxString(MUNIPACK_DATA_PATH) + "/ctable.dat");
#else
  Read(CDATAFILE, &cdatafile, "ctable.dat");
#endif


  // validate?

  default_icon = MuniIcon::DefaultIcon(icon_size,icon_size);
  munipack_icon = LoadIcon("munipack_icon.png");
  head_icon = LoadImage("head_icon.png");
  table_icon = LoadImage("table_icon.png");
  throbber = wxAnimation(FindPath("throbber.gif"));

}

MuniConfig::~MuniConfig()
{
  int k;

  Write(MUNIBROWSE_WIDTH,browser_size.GetWidth());
  Write(MUNIBROWSE_HEIGHT,browser_size.GetHeight());
  Write(MUNIBROWSE_SASH,browser_sash);
  Write(MUNIBROWSE_COLLECTOR,browser_collector);
  Write(MUNIBROWSE_TBAR,browser_tbar);
  Write(MUNIVIEW_WIDTH,view_size.GetWidth());
  Write(MUNIVIEW_HEIGHT,view_size.GetHeight());
  Write(MUNIVIEW_TBAR,view_tbar);
  Write(MUNIDETAIL_SCALE,detail_scale);
  Write(MUNIDETAIL_ZOOM,detail_zoom);
  Write(MUNICONSOLE_WIDTH,console_size.GetWidth());
  Write(MUNICONSOLE_HEIGHT,console_size.GetHeight());
  Write(MUNICONSOLE_WRAP,console_wrap);
  Write(MUNIHELP_WIDTH,help_size.GetWidth());
  Write(MUNIHELP_HEIGHT,help_size.GetHeight());
  Write(MUNIHEADER_WIDTH,header_size.GetWidth());
  Write(MUNIHEADER_HEIGHT,header_size.GetHeight());
  Write(ICON_SMALL,icon_small);
  Write(ICON_ZOOM,icon_zoom);

  switch(browser_iconlist){
  case wxLC_ICON:   k = 0; break;
  case wxLC_REPORT: k = 1; break;
  default: k = 0;
  }
  Write(MUNIBROWSE_ICONLIST,k);

  switch(browser_labeltype){
  case ID_LABEL_FILENAME: k = 0; break;
  case ID_LABEL_OBJECT:   k = 1; break;
  case ID_LABEL_DATEOBS:  k = 2; break;
  case ID_LABEL_FILTER:   k = 3; break;
  case ID_LABEL_EXPOSURE: k = 4; break;
  case ID_LABEL_KEY:      k = 5; break;
  case ID_LABEL_NO:       k = 6; break;
  default: k = 0;
  }
  Write(MUNIBROWSE_LABELTYPE,k);
  Write(MUNIBROWSE_LABELKEY,browser_labelkey);

  switch(browser_sorttype){
  case ID_SORT_FILENAME: k = 0; break;
  case ID_SORT_OBJECT:   k = 1; break;
  case ID_SORT_DATEOBS:  k = 2; break;
  case ID_SORT_FILTER:   k = 3; break;
  case ID_SORT_EXPOSURE: k = 4; break;
  case ID_SORT_SIZE:     k = 5; break;
  case ID_SORT_KEY:      k = 6; break;
  default: k = 0;
  }
  Write(MUNIBROWSE_SORTTYPE,k);

  Write(MUNIBROWSE_SORTKEY,browser_sortkey);
  Write(MUNIBROWSE_REVERSE,browser_reverse);
  Write(SCROLL_RATE,scroll_rate);
  Write(ASTROMETRY_NMATCH,astrometry_nmatch);
  Write(ASTROMETRY_MAXMATCH,astrometry_maxmatch);
  Write(ASTROMETRY_UNITS,astrometry_units);
  Write(DISPLAY_ITT,FitsItt::Type_str(display_itt));
  Write(DISPLAY_PAL,FitsPalette::Type_str(display_pal));
  Write(DISPLAY_ZOOM,display_zoom);
  Write(DISPLAY_NVISION,display_nvision);
  Write(FITS_OBJECT,fits_object);
  Write(FITS_OBSERVER,fits_observer);
  Write(FITS_DATEOBS,fits_dateobs);
  Write(FITS_EXPOSURE,fits_exposure);
  Write(FITS_FILTER,fits_filter);
  Write(COLOR_DISPLAY,display_colorspace);
  Write(COLOR_TEMPERATURE,color_temperature);
  Write(COLOR_WHITEPOINT_U,color_uwhitepoint);
  Write(COLOR_WHITEPOINT_V,color_vwhitepoint);
  Write(CDATAFILE,cdatafile);

}

wxString MuniConfig::FindPath(const wxString& name)
{
  wxArrayString p;

#ifdef __WXDEBUG__
  p.Add("icons");
#endif

  wxPathList paths(p);
  if( wxGetEnv("MUNIPACK_ICON",0) )
    paths.AddEnvList(wxString("MUNIPACK_ICON"));

#ifdef MUNIPACK_ICON_PATH
  paths.Add(wxString(MUNIPACK_ICON_PATH));
#endif

  wxString fullpath = paths.FindValidPath(name);
  return fullpath;
}

wxIcon MuniConfig::LoadIcon(const wxString& name)
{
  wxString fullpath = FindPath(name);

  wxIcon icon;
  if( ! fullpath.IsEmpty() ) {

    wxLogDebug(fullpath);
    wxImage icona(fullpath);
    if( icona.Ok() ) {
      wxBitmap bitmap(icona);
      icon.CopyFromBitmap(bitmap);
    }
  }

  if( ! icon.IsOk() )
    icon = wxArtProvider::GetIcon(wxART_MISSING_IMAGE,wxART_OTHER,wxDefaultSize);

  return icon;
}

wxImage MuniConfig::LoadImage(const wxString& name)
{
  wxString fullpath = FindPath(name);

  wxImage image;
  if( ! fullpath.IsEmpty() && image.LoadFile(fullpath) ) {
    wxLogDebug(fullpath);
    return image;
  } 
  else {
    wxBitmap b(wxArtProvider::GetBitmap(wxART_MISSING_IMAGE,wxART_OTHER,
					wxDefaultSize));
    return b.ConvertToImage();
  }
}


MuniArtIcons::MuniArtIcons(const wxArtClient& c, const wxSize& s):
  client(c), size(s) 
{}

wxBitmap MuniArtIcons::Icon(const wxArtID& id) const
{
#ifdef __WXMAC__
  wxString name;
  if( id == "zoom-fit-best" )
    name = "stock_zoom_fit_width");
  else if( id == "zoom-original" )
    name = "stock_zoom_one_to_one";
  else if( id == "preferences-desktop" )
    name = "stock_preferences";
  else if( id == "wxART_GO_UP" )
    name = "stock_up";
  else if( id == "wxART_GO_HOME" )
    name = "stock_home";
  else if( id == "wxART_GO_BACK" )
    name = "stock_back";
  else if( id == "wxART_GO_FORWARD" )
    name = "stock_forward";
  else if( id == "wxART_FOLDER" )
    name = "stock_folder";
  else if( id == "stop" )
    name = "stock_cancel";
  else if( id == "view-refresh" )
    name = "stock_refresh";

  wxString a(id);
  //  wxLogDebug(wxT("MuniArtIcons::Icon ") +a);
  wxString fullpath = MuniConfig::FindPath(name+".png");
  if( ! fullpath.IsEmpty() ) {

    //    wxLogDebug(wxT("MuniArtIcons::Icon %s"),fullpath.c_str());
    wxImage icona(fullpath);
    if( icona.Ok() ) {
      return wxBitmap(icona);
    }
  }
  return wxArtProvider::GetBitmap(wxART_MISSING_IMAGE,client,size);

#else

  wxBitmap b = wxArtProvider::GetBitmap(id,client,size);
  if( ! b.IsOk() ) 
    b = wxArtProvider::GetBitmap(wxART_MISSING_IMAGE,client,size);
  return b;
#endif
}
